const canvas = document.getElementById('canvas1');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const ctx = canvas.getContext('2d');


const collisonCanvas = document.getElementById('collisonCanvas');
collisonCanvas.width = window.innerWidth;
collisonCanvas.height = window.innerHeight;
const collisonCanvasCtx = collisonCanvas.getContext('2d');

let timeToNextRaven = 0;
const ravenInterval = 1000;
let lastTime = 0;

let ravens = [];

let score = 0;
let gameOver = false;
ctx.font = '50px Impact';

let particals = [];

class Pratical {
    constructor(x, y, size, color) {
        this.size = size;
        this.x = x + this.size / 2+Math.random()*50 -25;
        this.y = y + this.size / 2 +Math.random()*50 -25;
        this.radius = Math.random() * this.size / 10;
        this.maxRadius = Math.random() * 20 + 35;
        this.color = color;
        this.speedX = Math.random() * 1 + 0.5;
        this.markerOutOfRange = false;
    }
    update() {
        this.x += this.speedX;
        this.radius += 0.5;
        if (this.radius > this.maxRadius -5) {
            this.markerOutOfRange = true;
        }
    }
    draw() {
        ctx.save();
        ctx.globalAlpha = 1 - this.radius / this.maxRadius;
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        ctx.fill();
        ctx.restore();
    }
}

let explosions = [];

class Explosion {
    constructor(x, y, size) {
        this.spriteWidth = 200;
        this.spriteHeight = 179;
        this.x = x;
        this.y = y;
        this.size = size;
        this.image = new Image();
        this.image.src = "./explusion.png";
        this.sound = new Audio();
        this.sound.src = "./boom.wav";

        this.timeSinceLastFrame = 0;
        this.frameInterval = 500;
        this.frame = 0;

        this.markerOutOfRange = false;
    }
    update(deltatime) {
        if (this.frame === 0) {
            this.sound.play();
        }
        this.timeSinceLastFrame += deltatime;
        if (this.timeSinceLastFrame > this.frameInterval) {
            this.frame++;
            this.timeSinceLastFrame = 0;
            if (this.frame > 5) {
                this.markerOutOfRange = true;
            }
        }
    }
    draw() {
        ctx.drawImage(this.image, this.frame * this.spriteWidth, 0, this.spriteWidth, this.spriteHeight, this.x, this.y - this.size / 4, this.size, this.size)
    }
}

class Raven {
    constructor() {
        this.spriteWidth = 271;
        this.spriteHeight = 194;
        this.sizeModifier = Math.random() * 0.6 + 0.4
        this.width = this.spriteWidth * this.sizeModifier;
        this.height = this.spriteHeight * this.sizeModifier;
        this.x = canvas.width;
        this.y = Math.random() * (canvas.height - this.height);
        this.dirationX = Math.random() * 5 + 3;
        this.dirationY = Math.random() * 5 - 2.5;
        this.markerOutOfRange = false;

        this.image = new Image();
        this.image.src = "./raven.png";

        this.frame = 0;
        this.maxFrame = 4;

        this.timeSinceFlap = 0;
        this.flapInterval = Math.random() * 50 + 50;

        this.randomColor = [Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255)];
        this.color = `rgb(${this.randomColor[0]},${this.randomColor[1]},${this.randomColor[2]})`;

        this.hasTrail = Math.random() > 0.5;
    }
    update(deltatime) {
        if (this.y > canvas.height - this.height || this.y < 0) {
            this.dirationY = this.dirationY * -1;
        }
        this.x -= this.dirationX;
        this.y += this.dirationY;
        if (this.x < 0 - canvas.width) {
            this.markerOutOfRange = true;
        }
        this.timeSinceFlap += deltatime;
        if (this.timeSinceFlap > this.flapInterval) {
            if (this.frame < this.maxFrame) {
                this.frame++;
            } else {
                this.frame = 0;
            }
            this.timeSinceFlap = 0;

            if (this.hasTrail) {
                for(let i=0;i<5;i++){
                    particals.push(new Pratical(this.x, this.y, this.width, this.color))
                }
            }

        }
        if (this.x < 0) {
            gameOver = true;
        }

    }
    draw() {
        collisonCanvasCtx.fillStyle = this.color;
        collisonCanvasCtx.fillRect(this.x, this.y, this.width, this.height);
        ctx.drawImage(this.image, this.frame * this.spriteWidth, 0, this.spriteWidth, this.spriteHeight, this.x, this.y, this.width, this.height);
    }
}

function drawScore() {
    ctx.fillStyle = "black";
    ctx.fillText("Score: " + score, 50, 75);
    ctx.fillStyle = "white";
    ctx.fillText("Score: " + score, 55, 80)
}

function drawGameOver() {
    ctx.textAlign = "center";
    ctx.fillStyle = "black";
    ctx.fillText("GAME OVER your score is: " + score, canvas.width / 2, canvas.height / 2);
    ctx.fillStyle = "white";
    ctx.fillText("GAME OVER your score is: " + score, canvas.width / 2 + 5, canvas.height / 2 + 5);
}

window.addEventListener("click", function (e) {
    const detectPixelColr = collisonCanvasCtx.getImageData(e.x, e.y, 1, 1);
    const colorPixe = detectPixelColr.data;
    ravens.forEach(object => {
        if (object.randomColor[0] === colorPixe[0] && object.randomColor[1] === colorPixe[1] && object.randomColor[2] === colorPixe[2]) {
            object.markerOutOfRange = true;
            score++;
            explosions.push(new Explosion(object.x, object.y, object.width))
        }
    })
})



function animate(timestamp) {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    collisonCanvasCtx.clearRect(0, 0, canvas.width, canvas.height);
    const deltatime = timestamp - lastTime;
    lastTime = timestamp;
    timeToNextRaven += deltatime;
    if (timeToNextRaven > ravenInterval) {
        ravens.push(new Raven);
        timeToNextRaven = 0;
        ravens.sort(function (a, b) {
            return a.width - b.width
        })
    }
    drawScore();
    [...particals, ...ravens, ...explosions].forEach(object => object.update(deltatime));
    [...particals, ...ravens, ...explosions].forEach(object => object.draw());
    ravens = ravens.filter(object => !object.markerOutOfRange);
    explosions = explosions.filter(object => !object.markerOutOfRange);
    particals = particals.filter(object => !object.markerOutOfRange);
    if (!gameOver) {
        requestAnimationFrame(animate)
    } else {
        drawGameOver()
    }

};

animate(0);